package physics;



import globals.GlobalObjects;
import graphics.GraphicalObject;

import java.awt.event.ActionEvent;

import physics.Collisions.Collision;
import physics.MovementControl.AbstractMovementController;

import common.IParse;
import common.Math3D;
import common.Point3D;
import common.Position3D;


public class GameObject implements IParse {

	protected String name;
	protected String presentationName;
	protected Position3D position = new Position3D();
	double radius = 0.2;
	protected boolean moved = false;
	
	private AbstractMovementController movementControler = null;

	protected Planet planet;
	protected String planetName;
	protected boolean exists = true;
	private GraphicalObject graphicalObject;

	public GameObject(){

	} 

	public void clockTicked(ActionEvent arg0) {
		if (this.getMovementControler() != null){
			this.getMovementControler().play();
			setMoved(true);
		}
	}

	public void landOnPlanet(Planet planet)
	{
		this.getPlanet().removeObjectFromPlanet(this);
		this.setPlanet(planet);
		planet.addObjectToPlanet(this);
		planet.pinpointToPlanet(this);
		setMoved(true);
	}

	public void impact(Collision c){}


	public boolean moved() {
		return this.moved;
	}

	public boolean bumpedInto(GameObject objOnPlanet) {
		Point3D distance = Math3D.subPoint(objOnPlanet.getCenter(), this.getCenter());
		if (distance.norm() <= objOnPlanet.getRadius() + this.getRadius()){
			return true;
		}
		return false;
	}

	public void setMoved(boolean b) {
		this.moved = b;

	}


	public void setParameter(String name, String params[]){
		if (name.equals("presentation")) {
			presentationName = params[0];
		}
		if (name.equals("center")) {
			this.move(Double.parseDouble(params[0]),
					Double.parseDouble(params[1]), Double.parseDouble(params[2]));
		}
		if (name.equals("radius")) {
			this.radius = Double.parseDouble(params[0]);
		}
		if (name.equals("planet")) {
			this.planetName = params[0];
		}
	}

	public void commit(){
		Planet planet = (Planet) GlobalObjects.getGameObject(planetName);
		if (planet!= null){
			this.setPlanet(planet);
			planet.pinpointToPlanet(this);
		}
	}	


	public void rotateRight(double angle){
		Point3D newFace = new Point3D(Math.sin(angle),0,Math.cos(angle));
		Point3D newLeft = new Point3D(Math.cos(angle),0,-Math.sin(angle));
//		Point3D newUp = new Point3D(0,1,0);

		newFace.rotateWith(position.getLeft(), position.getUp(), position.getFace());
		newLeft.rotateWith(position.getLeft(), position.getUp(), position.getFace());
		position.getLeft().copy(newLeft);
		position.getFace().copy(newFace);

	}

	protected void rotateAttachedObject(GameObject object, Point3D left, Point3D up, Point3D face){
		object.position.getCenter().sub(this.position.getCenter());
		object.position.getCenter().rotateAgainst(left,up, face);
		object.position.getCenter().add(this.position.getCenter());
		object.position.getLeft().rotateAgainst(left,up, face);
		object.position.getUp().rotateAgainst(left,up, face);
		object.position.getFace().rotateAgainst(left,up, face);

	}

	public void moveFacingDirection(double distance){
		getCenter().add(Math3D.scalePoint(getFace(), distance));
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPresentationName() {
		return presentationName;
	}


	public void setPresentationName(String presentationName) {
		this.presentationName = presentationName;
	}

	public Planet getPlanet() {
		return planet;
	}

	public void setPlanet(Planet planet) {
		if (this.planet != null)
			this.planet.removeObjectFromPlanet(this);
		if (planet != null)
			planet.addObjectToPlanet(this);
		this.planet = planet;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}

	public Point3D getCenter() {
		return position.getCenter();
	}

	public void setCenter(Point3D center) {
		this.position.setCenter(center);
	}

	public Point3D getFace() {
		return position.getFace();
	}

	public void setFace(Point3D face) {
		this.position.setFace(face);
	}

	public Point3D getUp() {
		return position.getUp();
	}

	public void setUp(Point3D up) {
		this.position.setUp(up);
	}

	public Point3D getLeft() {
		return position.getLeft();
	}

	public void setLeft(Point3D left) {
		this.position.setLeft(left);
	}

	public void move(double x, double y, double z){
		this.position.move(x, y, z);
	}

	public Position3D getPosition() {
		return position;
	}

	public void setPosition(Position3D position) {
		this.position = position;
	}

	public void setMovementControler(AbstractMovementController movementControler) {
		this.movementControler = movementControler;
	}

	public AbstractMovementController getMovementControler() {
		return movementControler;
	}

	public boolean exists(){
		return this.exists;
	}

	public String getPlanetName() {
		return planetName;
	}
	public void setExists(boolean exists) {
		this.exists = exists;
	}

	public void setGraphicalObject(GraphicalObject grObj) {
		this.graphicalObject = grObj;
	}
	public GraphicalObject getGraphicalObject() {
		return this.graphicalObject;
	}
}
